package com.autonavi.yunda.yunji.service;

import com.autonavi.yunda.yunji.common.enums.EditType;
import com.autonavi.yunda.yunji.common.exception.AmapException;
import com.autonavi.yunda.yunji.common.exception.AmapExceptionCode;
import com.autonavi.yunda.yunji.core.enums.RoleType;
import com.autonavi.yunda.yunji.core.model.dto.InterfaceConfigDTO;
import com.autonavi.yunda.yunji.core.model.dto.ProjectDTO;
import com.autonavi.yunda.yunji.core.model.dto.TaskConfigDTO;
import com.autonavi.yunda.yunji.core.service.InterfaceConfigService;
import com.autonavi.yunda.yunji.core.service.ProjectService;
import com.autonavi.yunda.yunji.core.service.TaskConfigService;
import com.autonavi.yunda.yunji.core.vo.response.ProjectVO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 支持数据权限校验的ProjectService
 *
 * @author ruirui.cr@alibaba-inc.com
 */
@Component
@Slf4j
public class ProjectAuthService {
    @Resource
    private InterfaceConfigService interfaceConfigService;
    @Resource
    private UserProjectService userProjectService;
    @Resource
    private ProjectService projectService;
    @Resource
    private BucUserService bucUserService;
    @Resource
    private UserService userService;
    @Resource
    private FactoryUserService factoryUserService;
    @Resource
    TaskConfigService taskConfigService;

    public List<String> listAuthorizedProjectIds() {
        String userId = bucUserService.getCurEmployeeId();
        RoleType userRole = userService.getUserRole(userId);
        Long bdId = factoryUserService.getCurrentUserBdId();
        List<String> projectIds = projectService.listAll(bdId)
                .stream().map(ProjectDTO::getProjectId)
                .collect(Collectors.toList());
        if (RoleType.SUPER_ADMIN.equals(userRole)) {
            return projectIds;
        } else {
            List<String> userProjectIds = userProjectService.listUserProjectIds(userId);
            projectIds.retainAll(userProjectIds);
        }
        return projectIds;
    }

    /**
     * 获取所有授权的项目
     * @return
     */
    public List<ProjectVO> listAllAuthorizedProjects() {
        // 1.获取本用户授权的项目id集合
        List<String> authorizedProjectIdList = listAuthorizedProjectIds();
        if (authorizedProjectIdList.isEmpty()) {
            return new ArrayList<>();
        }
        // 2. 根据项目id获取项目实体集合
        List<ProjectDTO> projectDTOS = projectService.findByProjectIds(authorizedProjectIdList);
        // 3. 根据项目id获取该项目下接口的个数
        Map<String, Long> projectCountMap = interfaceConfigService.getProjectCountMap(authorizedProjectIdList);
        return projectDTOS.stream()
                .filter(dto -> authorizedProjectIdList.contains(dto.getProjectId()))
                .map(dto -> ProjectVO.fromDto(dto, projectCountMap))
                .collect(Collectors.toList());
    }

    public void checkProjectPermission(String projectId) {
        List<String> authorizedProjectIds = listAuthorizedProjectIds();
        if (!authorizedProjectIds.contains(projectId)) {
            throw new AmapException(AmapExceptionCode.NO_PERMISSION_ERROR);
        }
    }

    public void checkInterfaceProjectPermission(Long interfaceId) {
        InterfaceConfigDTO dto = interfaceConfigService.findByIdOrThrow(interfaceId);
        checkProjectPermission(dto.getProjectId());
    }

    public void checkProjectPermission(Long id, String editType) {
        if (EditType.TASK.name().equalsIgnoreCase(editType)) {
            TaskConfigDTO dto = taskConfigService.findByIdOrThrow(id);
            checkProjectPermission(dto.getProjectId());
        } else {
            checkInterfaceProjectPermission(id);
        }
    }

    /**
     * 检查当前登录用户是否具有管理员权限
     */
    public void checkSuperAdminPermission() {
        String userId = bucUserService.getCurEmployeeId();
        RoleType userRole = userService.getUserRole(userId);
        if(!RoleType.SUPER_ADMIN.equals(userRole)) {
            throw new AmapException(AmapExceptionCode.NO_PERMISSION_ERROR);
        }
    }

    /**
     * Check to see if current user is authorized to any one of the projects
     */
    public void checkPermissionAny(List<String> projectIds) {
        List<String> authorizedProjectIds = listAuthorizedProjectIds();
        authorizedProjectIds.retainAll(projectIds);
        if (authorizedProjectIds.isEmpty()) {
            throw new AmapException(AmapExceptionCode.NO_PERMISSION_ERROR);
        }
    }
}
